﻿using System;
using System.Drawing;
using LowLevelGraphics.ColorSpaces;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// Color Separate
    /// </summary>
    public class ColorSeparate : IExtractor
    {
        protected Type m_TypeOfAbstractColorSpace = typeof(XYZ);
        protected UnsafeBitmap[] m_aUnsafeBitmap = null;

        public delegate Color ColorSeparateDelegate(Color _Color, AbstractColorSpace _abstractColorSpace);
        public ColorSeparateDelegate[] m_aColorSeparateDelegate = null;

        protected AbstractColorSpace m_AbstractColorSpace = null;

        /// <summary>
        /// 
        /// </summary>
        public ColorSeparate()
        {

        }

        internal ColorSeparate(ColorSeparate _colorSeparate)
        {
        }

        public void Extract(UnsafeBitmap _bitmap)
        {
            //Get channels of color space (channelcount)
            AbstractColorSpace colorSpace = (AbstractColorSpace)Activator.CreateInstance(m_TypeOfAbstractColorSpace);
            object[] aValue = colorSpace.GetValues();
            int nValueCount = aValue.Length;

            m_aUnsafeBitmap = new UnsafeBitmap[nValueCount];
            int i=0;
            for (i = 0; i < nValueCount; i++)
            {
                m_aUnsafeBitmap[i] = (UnsafeBitmap)_bitmap.Clone();
            }
            for (i = 0; i < nValueCount; i++)
            {
                m_aUnsafeBitmap[i] = ExtractChannel( m_aUnsafeBitmap[i], m_aColorSeparateDelegate[i], i);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_unsafeBitmap"></param>
        /// <param name="_colorSeparateDelegate"></param>
        /// <returns></returns>
        public UnsafeBitmap ExtractChannel(UnsafeBitmap _unsafeBitmap, ColorSeparateDelegate _colorSeparateDelegate, int _nChannel)
        {
            int nWidth = _unsafeBitmap.Width;
            int nHeight = _unsafeBitmap.Height;
            for (int y = 0; y < nHeight; y++)
            {
                for (int x = 0; x < nWidth; x++)
                {
                    Color color = _unsafeBitmap.GetPixel(x, y);
                    color = _colorSeparateDelegate(color, m_AbstractColorSpace);
                    _unsafeBitmap.SetPixel(x, y, color);
                }   
            }
            return _unsafeBitmap;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_nIndex"></param>
        /// <returns></returns>
        public UnsafeBitmap this[int _nIndex]
        {
            get { return m_aUnsafeBitmap[_nIndex]; }
        }
    }
}